#pragma once
//============================================================================
// Copyright (C) 2003-2013 Brett R. Jones 
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses 
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================
#include <VxUtilLib/VxCommon.h>
#include <VxUtilLib/vx_debug.h>
#include "RcSysPktTypes.h"

#define RC_SYS_PKT_ANNOUNCE_VERSION 1
#define RC_SYS_ROGUE_ENGINE_VERSION 1

//=== action FLAGS ===//
#define RC_SYS_PKT_ACTION_ENTRY_NODE_ANN			0x0001
#define RC_SYS_PKT_ACTION_ENTRY_NODE_CONNECT		0x0002
#define RC_SYS_PKT_ACTION_TOP_TEN_ANN				0x0003
#define RC_SYS_PKT_ACTION_TOP_TEN_GET				0x0004
#define RC_SYS_PKT_ACTION_PING						0x0005
#define RC_SYS_PKT_ACTION_PONG						0x0006
#define RC_SYS_PKT_ACTION_TC_PLUGIN_CONNECT			0x0007

#define RC_SYS_PKT_ACTION_FIND_NODE					0x0008
#define RC_SYS_PKT_ACTION_FIND_PLUGIN				0x0009
#define RC_SYS_PKT_ACTION_FIND_FILE					0x000a
#define RC_SYS_PKT_ACTION_AUTH_CHANGE				0x000b


#pragma pack(push) 
#pragma pack(1)

//speed
// upper nibble 0-9
// lower nibble is number of trailing zeros
// example 0x54 = 50,000 bits per second

class RogueVersion
{
public:
	//=== vars ===//
	U8	m_u8RogueVersion;
	//=== constructor ===//
	RogueVersion();
	//=== methods ===//
	//! get version of rogue engine
	U8				getRogueVersion( void );
	//! get version of rogue engine as string
	void			getRogueVersion( std::string& strRetRougeVersion );
};

class RogueNetworkName
{
public:
	//=== vars ===//
	char	m_as8NetName[8];
	//=== constructor ===//
	RogueNetworkName();

	//=== methods ===//
	const char *	getNetworkName( void );
	void			setNetworkName( const char * pNetworkName );
};

//! pkt announce action data ( search etc )
//! size 6 bytes

#define FLAG_PKT_ANN_REQ_REPLY				0x01
#define FLAG_PKT_ANN_REQ_REV_CONNECT		0x02
#define FLAG_PKT_ANN_REQ_STUN				0x04


class RcSysPktAnnActionData
{
public:
	//=== vars ===//
	U32				m_u32ActionData;		// Action Data								
	U16				m_u16ActionFlags;		// Action Flags								
	U8				m_u8ActionRes;			// Reserved for future use	
	U8				m_u8RequestFlags;		// Reserved for future use								

	//=== constructor ===//
	RcSysPktAnnActionData();

	void		setIsPktAnnReplyRequested( bool bReqReply );
	bool		getIsPktAnnReplyRequested( void );
	void		setIsPktAnnRevConnectRequested( bool bReqConnect );
	bool		getIsPktAnnRevConnectRequested( void );
	void		setIsPktAnnStunRequested( bool bReqStun );
	bool		getIsPktAnnStunRequested( void );
};

//! this is the part of pkt announce that we would not expect to change often
//! can be used for quick check to see if we need to update info about friend to user
//! this is what we would send in list of pkt announcements
//! derived from 6+96+8 = 112
class RcSysPktAnnBase : public RcSysPktHdr, public VxNetIdent, public RcSysPktAnnActionData
{
public:
	//=== constructor ===//
	RcSysPktAnnBase();

	//=== methods ===//
	bool hasFriendDataChanged( RcSysPktAnnBase * poOther );

	//! make copy
	RcSysPktAnnBase *	MakeAnnBaseCopy( void );
};

//! pkt announce volatile vars used locally
//! size 8 bytes
class RcSysPktAnnVolitileVars
{
public:
	//=== vars ===//
	U32				m_u32TimeUdpLastContact;	// time of last contact via udp
	U8				m_u8ContactFlags;			// flags for big list etc
	U8				m_u8Flags;					// flags for offline etc
	U8				m_u8Res3;					// reserved
	U8				m_u8Res4;					// reserved
	//=== constructor ===//
	RcSysPktAnnVolitileVars();
};

//! is what we put in normal pkt announce so we can do actions etc
//! size is 112 + 8 + 8 bytes = 128 bytes total
class RcSysPktAnnounce : public RcSysPktAnnBase, public RogueNetworkName, public RcSysPktAnnVolitileVars
{
public:
	//=== vars ===//

	//=== constructor ===//
	RcSysPktAnnounce();

	//=== helpers ===//
	bool		isValidPktAnn( void );

	//=== methods ===//
	//! online status expires if no activity for specified time 
	bool		isOnlineStatusExpired( void );
	//! determine if udp timeout has expired ( used for guest permissions and nearby status )
	bool		isNearbyStatusExpired( void );
	//! if nearby then make permissions at least guest
	void		updateNearbyPermissions( void );

	//! get seconds since any last contact
	U32			getElapsedSecLastContact( void );
	//! get seconds since last tcp contact
	U32			getElapsedSecTcpLastContact( void );

	//---------------------------------------------------------------------------
	RcSysPktAnnounce *	MakeAnnCopy( void );
	//---------------------------------------------------------------------------
	RcSysPktAnnounce *	MakeAnnReverseCopy( void );
	//! dump contents of pkt announce for debug
	void		DebugDump( void );

	////! force friend offline by setting last contact time
	//void		forceFriendOffline( void )
	//{
	//	if( isFriendOnline() )
	//		IRcEngine::NotifyGuiOffline( this );
	//	if((g_u32SysTimeSec - m_u32TimeTcpLastContact) < ONLINE_STATUS_TIMEOUT_SECONDS)
	//	{
	//		m_u32TimeTcpLastContact = g_u32SysTimeSec - (ONLINE_STATUS_TIMEOUT_SECONDS + 1 );
	//	}
	//	m_u32TimeUdpLastContact = 0;
	//	m_oUdpIp = 0;
	//}
	////! called when recieved via tcp
	//void		setFriendConnected( void )		
	//{ 
	//	if( false == isFriendOnline() )
	//		IRcEngine::NotifyGuiOnline( this );
	//	m_u32TimeTcpLastContact = g_u32SysTimeSec;
	//}
	////! normally called when connection lost or have timed out
	//void		setFriendConnectionLost( void )			
	//{
	//	bool bWasOnline = isFriendOnline();
	//	m_u32TimeTcpLastContact = g_u32SysTimeSec - ( ONLINE_STATUS_TIMEOUT_SECONDS + 1);
	//	if( bWasOnline && ( false == isFriendOnline()) )
	//		IRcEngine::NotifyGuiOffline( this );
	//}
};


#pragma pack(pop)

